#include "exportdata.h"
#include "data/fpcompression.h"

#include <QFileDialog>
#include <QTextStream>

ExportData::ExportData(QList<GSData*>* dataSet, QWidget *parent) :
    QDialog(parent)
{
    exportDataSet = dataSet;
    setWindowTitle("Export Data");

    findButton.setText(tr("Find"));
    hlayout1.addWidget(&nameLineEdit);
    hlayout1.addWidget(&findButton);
    formLayout.addRow(tr("File Name:"), &hlayout1);
    formLayout.addRow(tr("File Format:"), &typeCombox);
    formLayout.addRow(tr("Data:"), &variableCombox);

    okButton.setText(tr("Save"));
    cancelButton.setText(tr("Cancel"));
    hlayout2.addWidget(&okButton);
    hlayout2.addWidget(&cancelButton);
    formLayout.addRow(&hlayout2);

    for(int i=0; i< dataSet->count(); i++)
        variableCombox.insertItem(i, dataSet->at(i)->name);

    QStringList typeName;
    typeName << tr("Text") << tr("GSPP");
    typeCombox.addItems(typeName);

    connect(&okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
    connect(&cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
    connect(&findButton, SIGNAL(clicked()), this, SLOT(findFilePath()));

    setLayout(&formLayout);
}

void ExportData::findFilePath()
{
    QString fileName
            = QFileDialog::getSaveFileName(
                this, tr("Save File Path"),
    ".", tr("Plain text files: *.txt *.csv (*.txt *.csv);;") +
                tr("GSPP file: *.gspp (*.gspp)") );
    nameLineEdit.setText(fileName);
}

void ExportData::okButtonClicked()
{
    if(nameLineEdit.text().isEmpty())
    {
        QMessageBox::warning(this, tr("Table Incomplete!"),
                           tr("Please Fulfil File Name.") );
        return;
    }

    if(variableCombox.count() < 1)
    {
        QMessageBox::warning(this, tr("Error!"),
                           tr("There are No Data For Export!\nPlease import data!") );
        return;
    }

    int errorCode = 0;
    switch (typeCombox.currentIndex()) {
    case 0: //Text
        errorCode += saveTextFile(exportDataSet->at(variableCombox.currentIndex()));
        break;
    case 1: //gspp
        errorCode += saveGsppFile(exportDataSet->at(variableCombox.currentIndex()));
        break;
    default://gspp
        errorCode += saveGsppFile(exportDataSet->at(variableCombox.currentIndex()));
        break;
    }

    if(errorCode<0)
    {
        QMessageBox::warning(this, tr("Error!"),
                           tr("Data Export Error!\n") );
        return;
    }
    else
    {
        QMessageBox::warning(this, tr("Notification!"),
                       tr("Data Export Successful!") );
        accept();
    }
}
//export gspp file
int ExportData::saveGsppFile(GSData* data)
{
    QString fileName = nameLineEdit.text();
    QString tempName = fileName + "~";
    QFile file(tempName); //temp file

    if (!file.open(QFile::WriteOnly | QFile::Truncate )) {
        QMessageBox::warning(this, tr("Error"), tr("Failed to open!\n"));
        return -1;
    }

    QDataStream out(&file);
    out.setByteOrder( QDataStream::LittleEndian);
    int dataLen = 0;
    int dataWidth = 0;
    switch (data->inDataType) {
    case GSData::VECTOR:
        out << (int)VECTOR_FLAG; //data type: vector
        dataLen = data->vecData.length();
        dataWidth = 1;
        out << dataLen; //data rows(length)
        out << dataWidth; //data cols(width)
        break;
    case GSData::MATRIX:
        out << (int)MATRIX_FLAG; //data type: matrix
        dataLen = data->matData.rows();
        dataWidth = data->matData.cols();
        out << dataLen; //data rows(length)
        out << dataWidth; //data cols(width)
        break;
    case GSData::ARRAY_VEC:
//       break;
    case GSData::ARRAY_MAT:
//       break;
    case GSData::STRING:
        QMessageBox::warning(this, tr("Sorry!"),
               tr("This type of data doesn't support.\n"));
        return -1;
    }

    for(int i=0; i<dataLen*dataWidth; i++)
    {
        switch (data->inDataType) {
        case GSData::VECTOR:
            out << data->vecData(i);
            break;
        case GSData::MATRIX:
            out << data->matData(i);
            break;
        case GSData::ARRAY_VEC:
    //       break;
        case GSData::ARRAY_MAT:
    //       break;
        case GSData::STRING:
            QMessageBox::warning(this, tr("Sorry!"),
                   tr("This type of data doesn't support.\n"));
           return -1;
        }
    }
    file.close();

    //compression
    FPCompression fpc;
    fpc.Compress(20, tempName.toStdString(), fileName.toStdString());
    remove(tempName.toStdString().c_str());

    return 0;
}

//export text file
int ExportData::saveTextFile(GSData* data)
{
    QFile file(nameLineEdit.text());

    if (!file.open(QFile::WriteOnly | QFile::Truncate )) {
        QMessageBox::warning(this, tr("Error"), tr("Failed to open!\n"));
        return -1;
    }

    QTextStream out(&file);

    int dataLen = 0;
    int dataWidth = 0;
    switch (data->inDataType) {
    case GSData::VECTOR:
        dataLen = data->vecData.length();
        break;
    case GSData::MATRIX:
        dataLen = data->matData.rows();
        dataWidth = data->matData.cols();
        break;
    case GSData::ARRAY_VEC:
//       break;
    case GSData::ARRAY_MAT:
//       break;
    case GSData::STRING:
        QMessageBox::warning(this, tr("Sorry!"),
               tr("This type of data doesn't support.\n"));
       return -1;
    }

    for(int i=0; i<dataLen; i++)
    {
        switch (data->inDataType) {
        case GSData::VECTOR:
            out << data->vecData(i) << "\n";
            break;
        case GSData::MATRIX:
            for(int j=0; j<dataWidth; j++)
                out << data->matData(i,j) << " ";
            out << "\n";
            break;
        case GSData::ARRAY_VEC:
    //       break;
        case GSData::ARRAY_MAT:
    //       break;
        case GSData::STRING:
            QMessageBox::warning(this, tr("Sorry!"),
                   tr("This type of data doesn't support.\n"));
            return -1;
        }
    }
    file.close();
    return 0;
}
